#include "CCharacter.h"


CCharacter::CCharacter() : CAnimatedObject()
{
	m_iMaxHp		= 1;
	m_iMaxMp		= 1;
	m_iHp			= m_iMaxHp;
	m_iMp			= m_iMaxMp;

	m_iMinDamage	= 0;
	m_iMaxDamage	= 1;
	m_iDefend		= 0;
	m_iLevel		= 0;

	m_pWeapon		= NULL;
	m_pArmor		= NULL;
	m_CurrentDir	= DIR_FORCE_DWORD;

	m_isDying		= false;

	
	for( ULONG i = 0 ; i < CALLBACK_COUNT ; ++i)
		ZeroMemory( &m_CallBack[i] , sizeof(CALLBACK_FUNC) );
}


CCharacter::CCharacter(float Xpos, float Ypos, float deep, float XVelocity, float YVelocity, int width, int height):CAnimatedObject( Xpos , Ypos , deep , XVelocity , YVelocity, width, height)
{
	m_iMaxHp		= 1;
	m_iMaxMp		= 1;
	m_iHp			= m_iMaxHp;
	m_iMp			= m_iMaxMp;

	m_iMinDamage	= 0;
	m_iMaxDamage	= 1;
	m_iDefend		= 0;
	m_iLevel		= 0;

	m_pWeapon		= NULL;
	m_pArmor		= NULL;
	m_CurrentDir	= DIR_FORCE_DWORD;

	m_isDying		= false;

	for( ULONG i = 0 ; i < CALLBACK_COUNT ; ++i)
		ZeroMemory( &m_CallBack[i] , sizeof(CALLBACK_FUNC) );
}

CCharacter::~CCharacter()
{
	if(m_pWeapon)
		delete m_pWeapon;
	if(m_pArmor)
		delete m_pArmor;

	m_pWeapon		= NULL;
	m_pArmor		= NULL;
	for( ULONG i = 0 ; i < CALLBACK_COUNT ; ++i)
		ZeroMemory( &m_CallBack[i] , sizeof(CALLBACK_FUNC) );
}




//----------------------------------------------//
// Name : SetLv									//
// Desc : Set the current lv for this character	//
//----------------------------------------------//
void CCharacter::SetLv(int lev)
{
	m_iLevel = lev;
}


//----------------------------------------------------------------------//
// Name : SetMaxAttribute												//
// Desc : Set the max attribute for this character ( maxHP , maxMP .. )	//
//----------------------------------------------------------------------//
void CCharacter::SetMaxAttribute(int maxHp, int maxMp)
{
	m_iMaxHp	= maxHp;
	m_iMaxMp	= maxMp;
}


//--------------------------------------------------------------------------//
// Name : SetCurrAttribute													//
// Desc : Set the current attribute for this character ( HP , MP , ... )	//
//--------------------------------------------------------------------------//
void CCharacter::SetCurrAttribute(int currHp, int currMp)
{
	if( currHp > m_iMaxHp || currMp > m_iMaxMp )
		return;

	m_iHp	= currHp;
	m_iMp	= currMp;
}



//--------------------------------------------------//
// Name : SetDamage									//
// Desc : Set max and min damage for this character	//
// Note : minDamage < maxDamage						//
//--------------------------------------------------//
void CCharacter::SetDamage(int minDamage, int maxDamage)
{
	if ( minDamage > maxDamage )
		return;

	m_iMaxDamage	= maxDamage;
	m_iMinDamage	= minDamage;
}



//--------------------------------------//
// Name : SetDefend						//
// Desc : Set defend for this character	//
//--------------------------------------//
void CCharacter::SetDefend(int def)
{
	m_iDefend = def;
}


//--------------------------------------//
// Name : SetWeapon						//
// Desc : Set weapon for this character	//
//--------------------------------------//
void CCharacter::SetWeapon(WEAPON *weapon)
{
	m_pWeapon = weapon;
}


//--------------------------------------//
// Name : SetArmor						//
// Desc : Set armor for this character	//
//--------------------------------------//
void CCharacter::SetArmor(ARMOR *armor)
{
	m_pArmor = armor;
}




//--------------------------------------------------//
// Name : SetDirection								//
// Desc : Set current direction for this character	//
//--------------------------------------------------//
void CCharacter::SetDirection( DIRECTION dir )
{
	m_CurrentDir = dir;
}



//------------------------------------------//
// Name : SetDying							//
// Desc : Set the character to dying phase	//
//------------------------------------------//
void CCharacter::SetDying(bool isDying /*= true*/)
{
	m_isDying = isDying;
}




//--------------------------------------------------//
// Name : GetMaxHp									//
// Desc : Get the max hit point of this character	//
//--------------------------------------------------//
int CCharacter::GetMaxHp()
{
	return m_iMaxHp;
}


//--------------------------------------------------//
// Name : GetMaxMp									//
// Desc : Get the max mana point of this character	//
//--------------------------------------------------//
int CCharacter::GetMaxMp()
{
	return m_iMaxMp;
}


//--------------------------------------------------//
// Name : GetHp										//
// Desc : Get current hit point of this character	//
//--------------------------------------------------//
int CCharacter::GetHp()
{
	return m_iHp;
}


//--------------------------------------------------//
// Name : GetMp										//
// Desc : Get current mana point of this character	//
//--------------------------------------------------//
int CCharacter::GetMp()
{
	return m_iMp;
}


//----------------------------------------------//
// Name : GetLv									//
// Desc : Get current level of this character	//
//----------------------------------------------//
int CCharacter::GetLv()
{
	return m_iLevel;
}


//----------------------------------//
// Name : GetPercentHp				//
// Desc : Get current hp in percent	//
//----------------------------------//
float CCharacter::GetPercentHp()
{
	return (float)( m_iHp * 100 ) / (float)m_iMaxHp ;
}


//----------------------------------//
// Name : GetPercentMp				//
// Desc : Get current mp in percent	//
//----------------------------------//
float CCharacter::GetPercentMp()
{
	return (float)( m_iMp * 100 ) / (float)m_iMaxMp ;
}



//----------------------------------------------//
// Name : GetMinDamage							//
// Desc : Get minimun damage of this character	//
//----------------------------------------------//
int CCharacter::GetMinDamage()
{
	return m_iMinDamage;
}


//----------------------------------------------//
// Name : GetMaxDamage							//
// Desc : Get maximum damage of this character	//
//----------------------------------------------//
int CCharacter::GetMaxDamage()
{
	return m_iMaxDamage;
}



//------------------------------------------//
// Name : GetDef							//
// Desc : Get the defend of this character	//
//------------------------------------------//
int CCharacter::GetDef()
{
	return m_iDefend;
}


//------------------------------------------------------//
// Name : GetCurrentDir									//
// Desc : Get the current direction of this character	//
//------------------------------------------------------//
CCharacter::DIRECTION CCharacter::GetCurrentDir()
{
	return m_CurrentDir;
}


//--------------------------------------------------//
// Name : isDying									//
// Desc : Check if the character is dying or not	//
//--------------------------------------------------//
bool CCharacter::isDying()
{
	return m_isDying;
}



//--------------------------------------------------//
// Name : RegisterCallback							//
// Desc : register a callback event for this object	//
//--------------------------------------------------//
void CCharacter::RegisterCallback( CALLBACK_TYPE Type , LPVOID pFunc, LPVOID pContext)
{
	if( Type > CALLBACK_COUNT )
		return;

	m_CallBack[Type].pContext	= pContext;
	m_CallBack[Type].pFunction	= pFunc;
}



//------------------------------------------------------//
// Name : ReduceHp										//
// Desc : Reduce character HP by amount of taken damage	//
//------------------------------------------------------//
void CCharacter::ReduceHp(int damgTaken)
{
	m_iHp -= damgTaken;
	if( m_iHp <= 0 )
		SetDying( );
}




//------------------------------------------------------//
// Name : ReduceMp										//
// Desc : Reduce character MP by amount of taken mana	//
//------------------------------------------------------//
void CCharacter::ReduceMp(int manaTaken)
{
	m_iMp -= manaTaken;
	if( m_iMp < 0 )
		m_iMp = 0;
}




//------------------------------------------------------//
// Name : DamageCal										//
// Desc : Calculating damage that this character has	//
//------------------------------------------------------//
int CCharacter::DamageCal()
{
	srand( timeGetTime() );
	int minDamg = m_iMinDamage + m_pWeapon->minDamage;
	int maxDamg = m_iMaxDamage + m_pWeapon->maxDamage;

	int totalDmg = rand() % minDamg + ( maxDamg - minDamg );

	return totalDmg;
}
